﻿#pragma once

#include "../lua_export_class.h"

namespace kratos {
namespace service {
class ServiceBox;
}
} // namespace kratos

namespace kratos {
namespace redis {
class RedisImpl;
class Result;
} // namespace redis
} // namespace kratos

namespace kratos {
namespace lua {

class LuaServiceImpl;

/**
 * @brief Redis类lua导出包装
 */
class LuaRedis : public LuaExportClass {
  kratos::service::ServiceBox *box_{nullptr}; ///< 服务容器
  lua_State *L_{nullptr};                     ///< lua虚拟机
  kratos::unique_pool_ptr<kratos::redis::RedisImpl> redis_ptr_; ///< Redis实例
  /**
   * @brief 命令信息
   */
  struct CommmandInfo {
    std::uint32_t thread_id; ///< 执行命令所在协程ID
    int result_type;         ///< 返回结果类型
  };
  using CommandThreadMap =
      kratos::service::PoolUnorederedMap<std::size_t, CommmandInfo>;
  CommandThreadMap command_thread_map_; ///< 命令与协程的对应关系
  std::size_t command_id_{1};           ///< 命令ID
  LuaServiceImpl *service_{nullptr};    ///< 服务容器
  bool started_{false};                 ///< 是否已经启动

public:
  /**
   * @brief 构造
   * @param box 服务容器
   * @param L 虚拟机
   * @param service lua服务
   */
  LuaRedis(kratos::service::ServiceBox *box, lua_State *L,
           LuaServiceImpl *service);
  /**
   * 析构
   */
  virtual ~LuaRedis();
  virtual auto do_register() -> bool override;
  virtual auto update(std::time_t ms) -> void override;
  virtual auto do_cleanup() -> void override;

private:
  /**
   * @brief redis返回回调
   * @param result 结果
   * @param command_id 命令ID 
   * @return true或false
  */
  auto result_callback(const kratos::redis::Result &result,
                       std::uint64_t command_id) -> bool;

private:
  static int lua_start(lua_State *l);
  static int lua_stop(lua_State *l);
  static int lua_add_host(lua_State *l);
  static int lua_do_command(lua_State *l);
};

} // namespace lua
} // namespace kratos
